/*
 * Код частково запозичено
 * http://it.kgsu.ru/ParalAlg/palg076.html
 */
#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 
#include <math.h> 
// Функція алгоритму методу Гауса-Зейделя
void ResultCalculation(double* pMatrix, int Size, double &Eps, 
int &Iterations) { 
double dm, dmax,temp; 
int i, j; // Змінні циклу 
Iterations = 0; 
do { 
dmax = 0; 
for (i = 1; i < Size - 1; i++) 
for(j = 1; j < Size - 1; j++) { 
temp = pMatrix[Size * i + j]; 
pMatrix[Size * i + j] = 0.25 * (pMatrix[Size * i + j + 1] + 
pMatrix[Size * i + j - 1] + 
pMatrix[Size * (i + 1) + j] + 
pMatrix[Size * (i - 1) + j]); 
dm = fabs(pMatrix[Size * i + j] - temp); 
if (dmax < dm) dmax = dm; 
} 
Iterations++; 
} 
while (dmax > Eps); 
} 
// Функція завершення обчислувального процесу
void ProcessTermination(double* pMatrix) { 
delete [] pMatrix; 
} 
// Функція форматованого виведення матриці 
void PrintMatrix(double* pMatrix, int RowCount, int ColCount) { 
int i, j; // Loop variables 
for (i=0; i<RowCount; i++) { 
for (j=0; j<ColCount; j++) 
printf("%7.4f ", pMatrix[i*ColCount+j]); 
printf("\n"); 
} 
} 
// Функція для протого задання значень вузлів сітки
void DummyDataInitialization(double* pMatrix, int Size) { 
int i, j; // Змінні циклу
double h = 1.0 / (Size - 1); 
// Задання значень вузлів сітки 
for (i=0; i<Size; i++) { 
for (j=0; j<Size; j++) 
if ((i==0) || (i== Size-1) || (j==0) || (j==Size-1)) 
pMatrix[i*Size+j] = 100; 
else 
pMatrix[i*Size+j] = 0; 
} 
} 
// Функція виділення пам'яті та ініціалізації
void ProcessInitialization(double* &pMatrix, int &Size, double &Eps) { 
// Задання розміру сітки
do { 
printf("\nEnter the grid size: "); 
scanf("%d", &Size); 
printf("\nChosen grid size = %d", Size); 
if (Size <= 2) 
printf("\nSize of grid must be greater than 2!\n"); 
} while (Size <= 2); 
// Задання необхідної точності
do { 
printf("\nEnter the required accuracy: "); 
scanf("%lf", &Eps); 
printf("\nChosen accuracy = %lf", Eps); 
if (Eps <= 2) 
printf("\nAccuracy must be greater than 0!\n"); 
} while (Eps <= 0); 
// Виділення пам'яті
pMatrix = new double [Size*Size]; 
// Задання значень вузлів сітки
DummyDataInitialization(pMatrix, Size); 
} 
int main() { 
double* pMatrix; // Матриця вузілів сітки 
int Size; // Розмір матриці
double Eps; // Необхідна точність 
int Iterations; // Кількість ітерацій
printf ("Serial Gauss - Seidel algorithm\n"); 
// Ініалізація процесу
ProcessInitialization(pMatrix, Size, Eps); 
// Вивід матриці
printf ("Initial Matrix: \n"); 
PrintMatrix (pMatrix, Size, Size); 
// Метод Гауса-Зейделя
ResultCalculation(pMatrix, Size, Eps, Iterations); 
// Вивід результатів
printf("\n Number of iterations: %d\n",Iterations); 
printf ("\n Result matrix: \n"); 
PrintMatrix (pMatrix, Size, Size); 
//getch(); 
// Звершення обчислювального процесу
ProcessTermination(pMatrix); 
} 
